Update module oras.land/oras-go/v2 to v2.6.1 [SECURITY] (main)#3378
Conversation
|
🤖 Finished Review · ✅ Success · Started 6:15 AM UTC · Completed 6:19 AM UTC |
ReviewVerdict: Comment — medium-severity finding worth noting but not blocking. SummaryThis PR updates The update is correctly applied to both the root Findings⚠ Incomplete security patch —
|
| Dimension | Result |
|---|---|
| Correctness | ⚠ Incomplete update in tools/go.mod |
| Security | ⚠ Same — incomplete patch coverage |
| Intent & coherence | ✅ Mechanical dependency bump, scope implicit |
| Style & conventions | ✅ No findings |
| Documentation currency | ✅ No docs affected |
| Cross-repo contracts | ✅ Skipped — no API surface changes |
Labels: Renovate security dependency update for Go module
Previous run
Review
Verdict: approve
This PR is a straightforward, automated security dependency update by Renovate, bumping oras.land/oras-go/v2 from v2.6.0 to v2.6.1. The update addresses four CVEs:
- CVE-2026-50151 (CVSS 7.5 High) — blob upload credential forwarding via unvalidated
Locationheader - CVE-2026-50162 (CVSS 6.9 Medium) — symlink traversal file write outside
workingDir - GHSA-vh4v-2xq2-g5cg (CVSS 6.9 Medium) — credential forwarding across registry redirects
- CVE-2026-48978 (CVSS 2.1 Low) — Bearer token realm hijack for SSRF/credential exfiltration
Changes reviewed
The diff is minimal and mechanical — version strings and checksums updated in go.mod and go.sum for both the root module and the acceptance/ module. The version is consistent across both modules (v2.6.1). No application code, configuration, or exported API surface is changed.
Findings
| # | Severity | Category | File | Description |
|---|---|---|---|---|
| 1 | low | incomplete-security-update | tools/go.mod:623 |
tools/go.mod still pins oras.land/oras-go/v2 at v2.6.0 (indirect dependency). While the primary CLI binary and acceptance tests are patched, the tools module retains the vulnerable version. Consider updating tools/go.mod and tools/go.sum as well for complete coverage. |
The tools module finding is low severity (indirect dependency in a development-tooling module) and does not block this PR. The critical path — the main CLI binary and acceptance test suite — is correctly updated.
Previous run (2)
Review
Verdict: comment · 1 finding
Summary
This is an automated security dependency update from Renovate that bumps oras.land/oras-go/v2 from v2.6.0 to v2.6.1 in both the root and acceptance/ Go modules. The update addresses four CVEs:
- CVE-2026-48978 — Bearer token realm hijack enabling SSRF and credential exfiltration (CVSS 2.1)
- CVE-2026-50151 — Blob upload credential forwarding via unvalidated
Locationheader (CVSS 7.5) - CVE-2026-50162 — File store write outside
workingDirvia symlink traversal (CVSS 6.9) - GHSA-vh4v-2xq2-g5cg — Credential forwarding across registry redirects (CVSS 6.9)
The diff is a clean, mechanical version bump — version strings updated in go.mod and corresponding hashes updated in go.sum for both modules. No source code, test, or configuration changes.
Findings
1. tools/go.mod still pins the vulnerable version — medium
File: tools/go.mod:623
The repository has three Go modules that depend on oras.land/oras-go/v2. This PR updates two of them (root and acceptance/), but tools/go.mod still pins v2.6.0 as an indirect dependency. Since this PR is tagged [SECURITY], the vulnerable version should ideally be updated across all modules to fully remediate the CVEs.
Remediation: Run go get oras.land/oras-go/v2@v2.6.1 && go mod tidy in the tools/ directory, or file a follow-up issue to track the update separately.
Dimensions reviewed
| Dimension | Result |
|---|---|
| Correctness | 1 medium finding (incomplete update) |
| Security | No concerns — update is a positive security improvement |
| Intent & coherence | Authorization implicit (mechanical Renovate bump) |
| Style & conventions | No findings (value-only change) |
| Documentation currency | No findings (no code/API changes) |
| Cross-repo contracts | Skipped (no exported interfaces modified) |
Previous run (3)
Review
Verdict: comment · 1 finding
This PR bumps oras.land/oras-go/v2 from v2.6.0 to v2.6.1, a security patch for CVE-2026-48978 (malicious registry Bearer token realm hijack → credential exfiltration). The version and checksum updates in go.mod/go.sum for the root and acceptance/ modules are correct and consistent.
However, the repository contains a third Go module at tools/ that also depends on the vulnerable version.
Findings
| # | Severity | Category | File | Description |
|---|---|---|---|---|
| 1 | medium | incomplete-change | tools/go.mod |
tools/go.mod (line 623) still pins oras.land/oras-go/v2 v2.6.0 as an indirect dependency, and tools/go.sum retains the v2.6.0 checksums. Since this is a security patch, any tooling built from the tools/ module will still pull in the vulnerable version. Run cd tools && go get oras.land/oras-go/v2@v2.6.1 && go mod tidy to complete the fix. |
Dimensions reviewed
- Correctness: One medium finding (incomplete module coverage). No logic errors — the changes in scope are mechanically correct.
- Security: No secrets, injection patterns, permission changes, or Unicode steganography detected in the diff. The upgrade itself is the correct remediation for CVE-2026-48978.
- Intent & coherence: Mechanical dependency bump by Renovate bot. Authorization inferred from automated nature of the change.
- Style & conventions: Value-only change following existing patterns. No findings.
- Documentation currency: No new public APIs or behavioral changes. No documentation staleness.
- Cross-repo contracts: No exported interfaces modified. Not applicable.
Previous run (4)
Review — approve
Security dependency update: oras.land/oras-go/v2 v2.6.0 → v2.6.1
Summary
Clean, mechanical dependency bump generated by Renovate to patch four upstream security vulnerabilities. Changes are limited to go.mod and go.sum in both the root and acceptance/ modules. No source code changes.
CVEs addressed
| CVE | Severity | Description |
|---|---|---|
| CVE-2026-50151 | High (7.5) | Credential forwarding via unvalidated Location header in blob upload |
| CVE-2026-50162 | Medium (6.9) | File store write outside workingDir via symlink traversal |
| GHSA-vh4v-2xq2-g5cg | Medium (6.9) | Credential forwarding across registry redirects |
| CVE-2026-48978 | Low (2.1) | Bearer token realm hijack for SSRF/credential exfiltration |
Relevance to this codebase
The library is actively used in three files:
internal/downloader/downloader.go— usesoras-go/v2/registry/remote/retryfor HTTP transport and retry policies when downloading policy sources. The credential forwarding fixes (CVE-2026-50151, GHSA-vh4v-2xq2-g5cg) are relevant here since this code interacts with remote OCI registries.acceptance/kubernetes/kind/image.go— usesoras-go/v2/content/file,oras-go/v2/registry/remote, andoras-go/v2directly for building and pushing OCI artifacts to the acceptance test registry. The symlink traversal fix (CVE-2026-50162) is relevant to theorasFile.New(".")usage, and the credential forwarding fixes apply to theremote.NewRepositoryinteractions.
Verification
- ✅ Version bump is consistent across both
go.modfiles (root andacceptance/) - ✅ Corresponding
go.sumhash entries are updated in both modules - ✅ No other dependency changes — clean, isolated security patch
- ✅ Patch version bump (v2.6.0 → v2.6.1) — expected to be backward-compatible
- ✅ No source code modifications required — fixes are entirely within the upstream library
No findings.
Previous run (5)
Looks good to me
Labels: PR is a Go dependency security update via Renovate
Codecov Report✅ All modified and coverable lines are covered by tests.
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
e940c79 to
c98bd07
Compare
|
🤖 Finished Review · ✅ Success · Started 9:43 AM UTC · Completed 9:46 AM UTC |
c98bd07 to
21aa3e8
Compare
|
🤖 Finished Review · ✅ Success · Started 1:02 PM UTC · Completed 1:07 PM UTC |
b080e7f to
d26c860
Compare
|
🤖 Finished Review · ✅ Success · Started 9:40 AM UTC · Completed 9:45 AM UTC |
d26c860 to
7feec71
Compare
|
🤖 Finished Review · ✅ Success · Started 2:40 PM UTC · Completed 2:46 PM UTC |
7feec71 to
4eb9d9e
Compare
|
🤖 Finished Review · ✅ Success · Started 3:30 PM UTC · Completed 3:37 PM UTC |
|
🤖 Finished Retro · ✅ Success · Started 9:28 PM UTC · Completed 9:35 PM UTC |
|
@fullsend-ai-retro I noticed the @fullsend-ai-review comment too late:
That was a good catch, sorry I missed it. I created #3391 to address this, and update tools/go.mod. Any idea why Renovate would have missed that one when generating this PR? |
|
PR #3378 on conforma/cli was a mechanical Renovate security dependency bump (oras.land/oras-go/v2 v2.6.0→v2.6.1), changing 4 files with +6/-6 lines. The PR sat open for 6 days (Jul 2–8) during which Renovate rebased the branch 6 times. Each rebase triggered a review agent run, resulting in 7+ total review runs on semantically identical diffs. The review agent correctly identified that tools/go.mod still pinned the vulnerable version (an out-of-diff file), but its verdict oscillated between 'approve' and 'comment' and the finding severity oscillated between 'low' and 'medium' across runs. A human approved with 'Lgtm.' without addressing the tools/go.mod finding. Three proposals filed as evidence for existing upstream issues covering redundant rebase-triggered reviews (#1355), verdict non-determinism (#3005), and out-of-diff finding verdict escalation (#1446). Proposals filed
|
This PR contains the following updates:
v2.6.0→v2.6.1oras-go: Malicious registry can hijack Bearer token realm to exfiltrate credentials and refresh tokens
CVE-2026-48978 / GHSA-xf85-363p-868w
More information
Details
Summary
oras-go's
auth.Clientfollows therealmURL from a registry'sWWW-Authenticate: Bearerchallenge without validating its scheme or host. Therealmfield is server-controlled by design in the OCI/distribution spec — registries legitimately point token requests at a separate auth endpoint (e.g. Docker Hub'sregistry-1.docker.io->auth.docker.io), so cross-host realms on public DNS names are not in themselves a vulnerability. Two specific patterns, however, are never legitimate under any registry trust model and can be abused by a malicious or compromised registry (or a man-in-the-middle on a plaintext connection):SSRF to internal networks. A realm of
http://169.254.169.254/...(AWS/Azure IMDS),http://10.0.0.x/...(RFC 1918), orhttp://127.0.0.1/...causes oras-go running on a cloud VM or corporate workstation to issue outbound HTTP requests from inside the user's trust boundary to an endpoint the user did not choose. The user's stored credentials are attached to those requests, but the principal harm is the network primitive — probing internal endpoints from the client. On IMDSv1 the response body is recoverable from log channels; on IMDSv2 the probe itself can still be used for service discovery.TLS downgrade. A registry contacted over
https://can return a realm with anhttp://scheme, causing oras-go to send the user's credentials over plaintext to the token endpoint. This defeats the transport security the user chose when typinghttps://.What is NOT claimed
This advisory does not claim that credential forwarding to an arbitrary public attacker host through a server-controlled realm is, on its own, a vulnerability. The distribution spec defines
realmas a server-controlled field; a strict same-host or same-eTLD+1 enforcement would deviate from the spec and break legitimate split-host deployments. Operators who want defense-in-depth against cross-host realm forwarding can use the opt-inClient.TrustedRealmHostsallowlist (added separately).Affected versions
oras.land/oras-go/v2 <= v2.6.0Severity
Medium. Network attack vector, low complexity, no privileges required, user interaction required (victim runs an oras command against the malicious or MITM'd registry), unchanged scope. Confidentiality impact is limited — IMDS probe responses can disclose information, and TLS downgrade exposes the realm request to passive observers — but the attacker does not obtain credentials beyond what the malicious endpoint already controls.
Affected code
registry/remote/auth/client.go—Client.Do()(bearer challenge handling)registry/remote/auth/client.go—Client.fetchBearerToken()/fetchDistributionToken/fetchOAuth2TokenThe
realmparameter fromparseChallengeis threaded through tohttp.NewRequestWithContextwithout scheme or host validation.CWE
Patch
registry/remote/auth/client.gonow rejects realm URLs that:httporhttpshttpwhen the registry was contacted overhttps(TLS downgrade)Cross-host realms on public DNS names continue to be accepted.
Credit
Reported by bugbunny.ai.
Severity
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:A/VC:L/VI:N/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
oras-go blob upload vulnerable to credential forwarding via unvalidated Location header
CVE-2026-50151 / GHSA-jxpm-75mh-9fp7
More information
Details
Summary
oras-go follows a registry-controlled
Locationheader during the monolithic blob upload flow and reuses theAuthorizationheader from the initialPOSTrequest for the subsequentPUTrequest. If a malicious registry returns a cross-hostLocation, oras-go can send the caller's credentials to an attacker-controlled endpoint.Affected Versions
tested: v2.6.0 (commit 03243809936cce826494b5506f724c6dc11115b1, as-of 2026-01-24)
range: unknown; likely affects earlier v2.x releases that include the same upload flow
Impact
Credential leak to an attacker-controlled endpoint and client-side ssrf to a cross-host target.
Affected Component
registry/remote/repository.go:878-916(blobStore.completePushAfterInitialPost)Reproduction
Attachments include
poc.zipwith a local-only harness (no real registry required). It runs a fake registry server that returns a cross-hostLocationand a second server that records whether it receivedAuthorization.unzip -q -o poc.zip -d /tmp/poc cd /tmp/poc/poc-F-ORAS-LOCATION-UPLOAD-001 make canonical make controlRecommended Fix
Locationbefore uploading (scheme + hostname + effective port) against the original request, or require an explicit opt-in allowlist for cross-host upload urlsAuthorizationwhen the upload target changes host or schemereferences
registry/remote/repository.go(seeblobStore.completePushAfterInitialPost)Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
oras-go has file store write outside workingDir via symlink traversal
CVE-2026-50162 / GHSA-8xwf-rjm4-xvhv
More information
Details
The file content store in
oras-goattempts to confine writes toworkingDirwhenAllowPathTraversalOnWrite=false, but the guard is lexical and does not account for symlink traversal. IfworkingDircontains a symlink path component and an attacker-controlled blob title (viaocispec.AnnotationTitle) targets a path under that symlink,pushFile()can create a file outsideworkingDir.relevant links
resolveWritePath()(used bypushFile())vulnerability details
pins: oras-project/oras-go@0324380
as-of: 2026-02-17
policy: GitHub Security Advisory (oras-project/oras-go)
callsite: content/file/file.go:609
resolveWritePath()→pushFile()attacker control: Attacker controls the pushed name (
ocispec.AnnotationTitle) and can select a path with a symlink path component underworkingDir→resolveWritePath()blocks..viafilepath.Relbut does not prevent symlink traversal →pushFile()opens/creates the final path and follows the symlink → a file is created outsideworkingDirroot cause
resolveWritePath()enforces the write boundary using afilepath.Rel-style check againstworkingDir. This prevents../escapes but is purely lexical and does not resolve symlinks. If a path component underworkingDiris a symlink to an external location, the subsequent filesystem operation inpushFile()follows that symlink and performs the write outsideworkingDirwhile still passing the lexical boundary check.attack path
ocispec.AnnotationTitle) that contains a path likeout/pwn.txt.oras-gofile store withAllowPathTraversalOnWrite=falseand aworkingDirthat contains a symlink directoryout -> /some/outside/dir.out/pwn.txtas being underworkingDir./some/outside/dir/pwn.txt.impact
This is a filesystem boundary bypass that permits writes outside
workingDirwhen a symlink path component exists underworkingDir. The concrete security impact depends on the runtime environment (what filesystem locations are writable by the process and what downstream consumers do with the written file), but the intended confinement guarantee is violated.proof of concept
the attached
poc.zipcontains a small, self-contained go harness that demonstrates:[CALLSITE_HIT]and[PROOF_MARKER]and shows the file is created outsideworkingDir[NC_MARKER]and confirms no outside write occursrun:
expected: when
AllowPathTraversalOnWrite=false, file store writes should not be able to escapeworkingDir, including via symlink traversal.actual: A symlink path component under
workingDirallows writes to escapeworkingDireven whenAllowPathTraversalOnWrite=false.recommended fix
ensure confinement checks account for symlink traversal. Options include rejecting symlinks in any path component (walk components with
os.Lstat), validating the resolved parent directory viaEvalSymlinksand enforcing it remains under the resolvedworkingDir, or using anopenat()-style approach so the check and open happen relative to a trusted directory file descriptor.fix accepted when: The canonical PoC no longer prints
[PROOF_MARKER]for the same attacker-controlled inputs.cheers,
Oleh
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
ORAS Go forwards registry credentials across registry redirects
GHSA-vh4v-2xq2-g5cg
More information
Details
ORAS Go forwards registry credentials across registry redirects
Reporter / public credit: JUNYI LIU
Summary
ORAS Go can forward registry credentials configured for one registry origin to a different HTTP origin during registry redirects.
There are two related paths:
Authorizationheader to the redirect target.POSTauthenticates to the origin registry, then the origin returns an uploadLocationon another host or port. The follow-upPUTcan carry the originAuthorizationheader to theLocationtarget.The upload
Locationissue appears related to the existing public fix in pull request #1152 / GHSA-jxpm-75mh-9fp7. The manifest redirect path is a residual adjacent route: the v2 branch after the uploadLocationfix still forwards Basic credentials on an authenticated manifest redirect.Impact
A registry response can cause an ORAS Go or ORAS CLI client to send configured registry credentials to an unintended endpoint. In common workflows, those credentials may come from a registry config / Docker-style auth file rather than command-line flags.
This is a credential exposure across the registry-origin boundary. I am not claiming remote code execution, registry compromise, arbitrary token theft, or live third-party impact.
Affected Versions Tested
oras-go v2.6.0: affected.oras-gomain at commita57383e580c8f2c97fb67dedfc5c9945c8c3614e: affected.oras-gov2 branch at commitd593d504779be8b69f0ba034ac9fd407d1fc8cfc: uploadLocationpath is blocked, but manifest redirect credential forwarding is still affected.3d2646279c70ba60415440e44c2ff97896e4a209, usingoras-go v2.6.0: affected when using--registry-config.Security Invariant
Credentials resolved for one registry origin should not be silently forwarded to a different origin reached through a registry redirect or upload
Locationresponse.Local Reproduction Overview
All testing used loopback servers and fake credentials only.
Manifest redirect flow:
401with a Basic challenge.307to another port on the same hostname.Authorizationheader.ORAS CLI stored-credential flow:
Authorizationheader.Blob upload
Locationflow:POSTto the origin registry.POST.LocationURL on another port.PUTto theLocationtarget carries the originAuthorizationheader.Expected Result
Redirect and upload
Locationtargets on a different HTTP origin should not receive the originAuthorizationheader.Observed Result
In affected versions, redirect or
Locationsinks received:Authorization: Basic <base64 origin_user:origin_pass>Standalone Reproducer
Candidate Fix
The candidate fix does two things:
Authorizationis removed when a redirect changes HTTP origin, while preserving any caller-providedCheckRedirectcallback.POSTAuthorizationheader when the uploadLocationremains on the same HTTP origin.The patch also adds regression coverage for both redirect cases:
Validation Performed
The repaired candidate fix blocked:
Locationcredential forwarding.Targeted tests passed:
Prior Art / Duplicate Notes
Public pull request #1152 fixes credential forwarding via unvalidated blob upload
Locationand references GHSA-jxpm-75mh-9fp7. The residual manifest redirect path described here is adjacent but not covered by that PR's stated uploadLocationscope.Bearer realm credential exfiltration appears to be a separate issue family and is not part of this report's primary claim.
Claim Boundaries
Proven:
Locationorigin in local loopback tests.Locationcredential exposures.Not claimed:
Locationorigin transitions.Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.